/*
 * Copyright 2023 devaper
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.github.devaper.pigeon.handler.method

import io.github.devaper.pigeon.*
import io.github.devaper.pigeon.component.*
import io.github.devaper.pigeon.factory.*
import io.github.devaper.pigeon.handler.argument.*
import io.github.devaper.pigeon.intercept.*
import io.github.devaper.pigeon.request.*
import io.github.devaper.pigeon.response.*

/**
 * 实现了基本功能的 [MethodHandler], 用于发送Http请求
 *
 * @param requestBasicInfo [RequestBasicInfo]
 * @param httpClientEngine [HttpClientEngine]
 * @param httpMessageConverter [HttpMessageConverter]
 * @param requestInterceptor [RequestInterceptor] 如果没有可以传如 [RequestInterceptor.EMPTY]
 * @param methodContext [MethodContext]
 * @param argumentHandler [ArgumentHandler]
 * @param retryConfig [RetryConfig]
 */
abstract class AbstractHttpMethodHandler(
    val requestBasicInfo: RequestBasicInfo,
    val httpClientEngine: HttpClientEngine,
    val httpMessageConverter: HttpMessageConverter,
    val requestInterceptor: RequestInterceptor,
    val methodContext: MethodContext,
    val argumentHandler: ArgumentHandler,
    val fallbackInstance: Any?,
    val retryConfig: RetryConfig?
) : MethodHandler {
    override fun handle(args: Array<out Any?>): Any? {
        // 创建请求模板
        val requestTemplate = RequestTemplate(
            methodHandler = this,
            requestMethod = requestBasicInfo.requestMethod,
            requestUrl = requestBasicInfo.requestPathSupplier.get()
        )
        // 执行参数处理器
        argumentHandler.handle(
            methodHandler = this,
            parameterIndex = -1,
            arguments = args,
            requestTemplate = requestTemplate
        )

        // 执行请求拦截器
        requestInterceptor.intercept(
            methodContext = methodContext,
            requestTemplate = requestTemplate
        )

        return createDeferred(requestTemplate, args)
    }

    /**
     * 根据请求模板创建一个Deferred
     *
     * 这个方法中需要发送Http请求并组装Deferred
     *
     * @param requestTemplate 请求模板
     * @param args 调用时提供的参数
     * @return Deferred
     */
    abstract fun createDeferred(requestTemplate: RequestTemplate, args: Array<out Any?>): Deferred<Any>
}